package sideeffect

import (
	"context"
	"errors"
	"github.com/nuttech/bell"
	"github.com/stretchr/testify/mock"
	"gitverse.ru/synapse/kubelatte/pkg/api/v1alpha1"
	"gitverse.ru/synapse/kubelatte/pkg/kubeapi"
	"gitverse.ru/synapse/kubelatte/pkg/operator"
	"gitverse.ru/synapse/kubelatte/pkg/operator/controllers/clientset"
	mocks2 "gitverse.ru/synapse/kubelatte/pkg/operator/controllers/clientset/mocks"
	"gitverse.ru/synapse/kubelatte/pkg/storage"
	errors2 "k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime/schema"
	"k8s.io/client-go/kubernetes"
	"sync"
	"testing"
	"time"
)

// hashes should be different only if one of ControlFields have diffs (ann, labels, spec or data)
func TestController_getObjControlFieldsHash_SimilarHashes(t *testing.T) {
	type args struct {
		obj map[string]any
	}
	tests := []struct {
		name    string
		args1   args
		args2   args
		args3   args
		want    string
		wantErr bool
	}{
		{
			name: "equal hashes annots + labels",
			args1: args{obj: map[string]any{
				"metadata": map[string]any{
					"name":        "some_name1",
					"namespace":   "incl_ns1",
					"annotations": map[string]any{prefix + ".annotNS/annotTr": "Enabled"},
					"labels": map[string]any{
						prefix + ".key1": "val1",
						prefix + ".key2": "val2",
						prefix + ".key3": "val3"},
				},
			}},
			args2: args{obj: map[string]any{
				"metadata": map[string]any{
					"name":        "some_name2",
					"field":       "incl_ns2",
					"annotations": map[string]any{prefix + ".annotNS/annotTr": "Enabled"},
					"labels": map[string]any{
						"key_without_pref333333": "val",
						prefix + ".key1":         "val1",
						prefix + ".key2":         "val2",
						prefix + ".key3":         "val3"}},
			}},
			args3: args{obj: map[string]any{
				"metadata": map[string]any{
					"name":        "some_name3",
					"namespace":   "incl_ns3",
					"annotations": map[string]any{prefix + ".annotNS/annotTr": "Enabled"},
					"labels": map[string]any{
						"key_without_pref1": "val",
						"key_without_pref2": "val",
						"key_without_pref3": "val",
						"key_without_pref4": "val",
						"key_without_pref5": "val",
						"key_without_pref6": "val",
						prefix + ".key1":    "val1",
						"key_without_pref7": "val",
						"key_without_pref8": "val",
						prefix + ".key2":    "val2",
						"key_without_pref9": "val",
						prefix + ".key3":    "val3"}},
			}},
			want:    "10562426954055529816",
			wantErr: false,
		},
		{
			name: "equal hashes spec + data",
			args1: args{obj: map[string]any{
				"metadata": map[string]any{
					"name":      "some_name1",
					"namespace": "incl_ns1",
					"spec":      map[string]any{"img": "image]"},
					"data":      map[string]any{"key1": "val1", "key2": "val2", "key3": "val3"},
				},
			}},
			args2: args{obj: map[string]any{
				"metadata": map[string]any{
					"name":  "some_name2",
					"field": "incl_ns2",
					"spec":  map[string]any{"img": "image]"},
					"data":  map[string]any{"key1": "val1", "key2": "val2", "key3": "val3"},
				},
			}},
			args3: args{obj: map[string]any{
				"metadata": map[string]any{
					"name":      "some_name3",
					"namespace": "incl_ns3",
					"spec":      map[string]any{"img": "image]"},
					"data":      map[string]any{"key1": "val1", "key2": "val2", "key3": "val3"},
				},
			}},
			want:    "10562426954055529816",
			wantErr: false,
		},
		{
			name: "equal hashes annots + labels + spec + data",
			args1: args{obj: map[string]any{
				"metadata": map[string]any{
					"name":        "some_name1",
					"namespace":   "incl_ns1",
					"spec":        map[string]any{"img": "image]"},
					"data":        map[string]any{"key1": "val1", "key2": "val2", "key3": "val3"},
					"annotations": map[string]any{prefix + ".annotNS/annotTr": "Enabled"},
					"labels": map[string]any{
						"key_without_pref1": "val",
						"key_without_pref2": "val",
						"key_without_pref3": "val",
						"key_without_pref4": "val",
						"key_without_pref5": "val",
						"key_without_pref6": "val",
						prefix + ".key1":    "val1",
						"key_without_pref7": "val",
						"key_without_pref8": "val",
						prefix + ".key2":    "val2",
						"key_without_pref9": "val",
						prefix + ".key3":    "val3"}},
			},
			},
			args2: args{obj: map[string]any{
				"metadata": map[string]any{
					"name":        "some_name2",
					"field":       "incl_ns2",
					"spec":        map[string]any{"img": "image]"},
					"data":        map[string]any{"key1": "val1", "key2": "val2", "key3": "val3"},
					"annotations": map[string]any{prefix + ".annotNS/annotTr": "Enabled"},
					"labels": map[string]any{
						"key_without_pref333333": "val",
						prefix + ".key2":         "val2",
						prefix + ".key1":         "val1",
						prefix + ".key3":         "val3"},
				},
			}},
			args3: args{obj: map[string]any{
				"metadata": map[string]any{
					"name":        "some_name3",
					"namespace":   "incl_ns3",
					"spec":        map[string]any{"img": "image]"},
					"data":        map[string]any{"key1": "val1", "key2": "val2", "key3": "val3"},
					"annotations": map[string]any{prefix + ".annotNS/annotTr": "Enabled"},
					"labels": map[string]any{
						prefix + ".key1": "val1",
						prefix + ".key2": "val2",
						prefix + ".key3": "val3"},
				},
			}},
			want:    "10562426954055529816",
			wantErr: false,
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			c := &Executor{}

			got1, err1 := c.getObjControlFieldsHash(context.Background(), tt.args1.obj)
			got2, err2 := c.getObjControlFieldsHash(context.Background(), tt.args2.obj)
			got3, err3 := c.getObjControlFieldsHash(context.Background(), tt.args3.obj)

			if (err1 != nil) != tt.wantErr || (err2 != nil) != tt.wantErr || (err3 != nil) != tt.wantErr {
				t.Errorf("getObjControlFieldsHash() errors: %v, %v, %v, wantErr %v", err1.Error(), err2.Error(), err3.Error(), tt.wantErr)
				return
			}

			if got1 != tt.want {
				t.Errorf("getObjControlFieldsHash() got = %v, want %v", got1, tt.want)
			}
			if got2 != tt.want {
				t.Errorf("getObjControlFieldsHash() got = %v, want %v", got2, tt.want)
			}
			if got3 != tt.want {
				t.Errorf("getObjControlFieldsHash() got = %v, want %v", got3, tt.want)
			}

			if got1 != got2 || got2 != got3 {
				t.Errorf("results are not equal to each ther: \n1: %v, \n2: %v, \n3: %v", got1, got2, got3)
			}
		})
	}
}

func TestController_getObjControlFieldsHash_DiffHashes(t *testing.T) {
	type args struct {
		obj map[string]any
	}
	tests := []struct {
		name    string
		args1   args
		args2   args
		want    string
		wantErr bool
	}{
		{
			name: "equal hashes annots + labels",
			args1: args{obj: map[string]any{
				"metadata": map[string]any{
					"name":        "some_name1",
					"namespace":   "incl_ns1",
					"annotations": map[string]any{prefix + ".annotNS/annotTr": "Enabled"},
					"labels": map[string]any{
						prefix + ".key1": "val1",
						prefix + ".key2": "val2",
						prefix + ".key3": "val3"},
				},
			}},
			args2: args{obj: map[string]any{
				"metadata": map[string]any{
					"name":        "some_name2",
					"field":       "incl_ns2",
					"annotations": map[string]any{prefix + ".annotNS/annotTr": "Enabled"},
					"labels": map[string]any{
						"key_without_pref333333": "val",
						prefix + ".key1":         "val1",
						prefix + ".key2":         "val2",
						prefix + ".key3":         "val3"}},
			}},
			want:    "10562426954055529816",
			wantErr: false,
		},
		{
			name: "equal hashes spec + data",
			args1: args{obj: map[string]any{
				"metadata": map[string]any{
					"name":      "some_name1",
					"namespace": "incl_ns1",
					"spec":      map[string]any{"img": "image]"},
					"data":      map[string]any{"key1": "val1", "key2": "val2", "key3": "val3"},
				},
			}},
			args2: args{obj: map[string]any{
				"metadata": map[string]any{
					"name":  "some_name2",
					"field": "incl_ns2",
					"spec":  map[string]any{"img": "image]"},
					"data":  map[string]any{"key1": "val1", "key2": "val2", "key3": "val3"},
				},
			}},
			want:    "10562426954055529816",
			wantErr: false,
		},
		{
			name: "equal hashes annots + labels + spec + data",
			args1: args{obj: map[string]any{
				"metadata": map[string]any{
					"name":      "some_name1",
					"namespace": "incl_ns1",
					"spec":      map[string]any{"img": "image]"},
					"data":      map[string]any{"key1": "val1", "key2": "val2", "key3": "val3"},
					"labels": map[string]any{
						"key_without_pref1": "val",
						"key_without_pref2": "val",
						"key_without_pref3": "val",
						"key_without_pref4": "val",
						"key_without_pref5": "val",
						"key_without_pref6": "val",
						prefix + ".key1":    "val1",
						"key_without_pref7": "val",
						"key_without_pref8": "val",
						prefix + ".key2":    "val2",
						"key_without_pref9": "val",
						prefix + ".key3":    "val3"}},
			},
			},
			args2: args{obj: map[string]any{
				"metadata": map[string]any{
					"name":        "some_name2",
					"field":       "incl_ns2",
					"spec":        map[string]any{"img": "image]"},
					"data":        map[string]any{"key1": "val1", "key2": "val2", "key3": "val3"},
					"annotations": map[string]any{prefix + ".annotNS/annotTr": "Enabled"},
					"labels": map[string]any{
						"key_without_pref333333": "val",
						prefix + ".key1":         "val1",
						prefix + ".key2":         "val2",
						prefix + ".key3":         "val3"},
				},
			}},
			want:    "10562426954055529816",
			wantErr: false,
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			c := &Executor{}

			got1, err1 := c.getObjControlFieldsHash(context.Background(), tt.args1.obj)
			got2, err2 := c.getObjControlFieldsHash(context.Background(), tt.args1.obj)
			got3, err3 := c.getObjControlFieldsHash(context.Background(), tt.args1.obj)

			if (err1 != nil) != tt.wantErr || (err2 != nil) != tt.wantErr || (err3 != nil) != tt.wantErr {
				t.Errorf("getObjControlFieldsHash() errors: %v, %v, %v, wantErr %v", err1.Error(), err2.Error(), err3.Error(), tt.wantErr)
				return
			}

			if got1 != tt.want {
				t.Errorf("getObjControlFieldsHash() got = %v, want %v", got1, tt.want)
			}
			if got2 != tt.want {
				t.Errorf("getObjControlFieldsHash() got = %v, want %v", got1, tt.want)
			}
			if got3 != tt.want {
				t.Errorf("getObjControlFieldsHash() got = %v, want %v", got1, tt.want)
			}

			if got1 != got2 || got2 != got3 {
				t.Errorf("results are not equal to each ther: \n1: %v, \n2: %v, \n3: %v", got1, got2, got3)
			}
		})
	}
}

func TestController_applySideEffectRecreate(t *testing.T) {
	type fields struct {
		kubeCli        *kubernetes.Clientset
		kbtlKubeClient clientset.V1Alpha1Interface
		mu             *sync.Mutex
	}
	type args struct {
		ctx  context.Context
		info *SE
	}
	tests := []struct {
		name     string
		fields   fields
		setVars  func()
		template v1alpha1.Template
		trigger  v1alpha1.Trigger
		args     args
	}{
		{
			name: "success recreation",
			setVars: func() {
				kubeapi.GetResourceMeta = func(client *kubernetes.Clientset, kind string, version string) *kubeapi.ResourceMeta {
					return &kubeapi.ResourceMeta{
						Name:         "Pod",
						Plural:       "pods",
						Path:         "api",
						Namespaced:   true,
						GroupVersion: "v1",
					}
				}
				operator.TimeoutParentWaiting = 2 * time.Second
				kubeapi.GetResource = func(ctx context.Context, resourceMeta *kubeapi.ResourceMeta, resourceName string, namespaceName string) ([]byte, error) {
					return []byte("{\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"name\":\"pod-se-plus-mutation\",\"resourceVersion\": \"verse1\",\"uid\": \"31ce6848-bee4-40fb-be85-7f796dd11685\",\"namespace\":\"kate-kblt-dev\",\"labels\":{\"sidecar.istio.io/inject\":\"false\",\"side-effect-plus-mutation\":\"enabled\"},\"annotations\":{\"kblt.annot-ns/merge\":\"enabled\", \"kblt.sideEffect.resource/tag\": \"5\"}},\"spec\":{\"hostNetwork\":false,\"serviceAccount\":\"default\",\"serviceAccountName\":\"default\",\"restartPolicy\":\"Never\",\"automountServiceAccountToken\":false,\"securityContext\":{\"runAsNonRoot\":true,\"seccompProfile\":{\"type\":\"RuntimeDefault\"}},\"containers\":[{\"image\":\"dzo.sw.sbc.space/sbt_dev/ci90000221_fedmesh_dev/federation-demo@sha256:548cc416011c86bb1e2c6d06289aab0771a0f749c044656deaac5fc86d891fea\",\"name\":\"test\",\"imagePullPolicy\":\"Always\",\"securityContext\":{\"allowPrivilegeEscalation\":false,\"capabilities\":{\"drop\":[\"ALL\"]},\"runAsNonRoot\":true,\"privileged\":false}}]}}"), nil
				}
			},
			trigger: v1alpha1.Trigger{
				ObjectMeta: metav1.ObjectMeta{Name: "TriggerName", Namespace: "TriggerNamespace"},
				Spec: v1alpha1.TriggerSpec{
					SideEffectConfigs: []v1alpha1.SideEffectConfig{{
						Name:         "SideEffConfigName",
						TemplateRefs: []string{"templNs/templName"},
					}}},
			},
			template: v1alpha1.Template{
				ObjectMeta: metav1.ObjectMeta{
					Namespace: "templNs",
					Name:      "templName",
				},
				Spec: v1alpha1.TemplateSpec{
					Data: "---\nkind: TriggerInstance\napiVersion: kubelatte.synapse.sber/v1alpha1\nmetadata:\n  name: trigger-instance-se-plus-mutation\n  annotations:\n    kblt/side-effect-plus-mutation: enabled\nspec:\n  data: data\n",
				},
			},
			args: args{
				info: &SE{
					SeMode: int32(Recreation),
					Configs: Configs{
						Kind:       "Pod",
						ApiVersion: "v1",
						Metadata: Metadata{
							Namespace: "kblt-dev",
							Name:      "podik :D ! XD",
						},
						ParentTag:    5,
						TemplateRefs: []string{"templNs/templName"},
						TriggerRef: TriggerRef{
							Name:             "TriggerName",
							Namespace:        "TriggerNamespace",
							SideEffectConfig: "SideEffConfigName",
						},
					},
				}},
		},
		{
			name: "empty timeout",
			setVars: func() {
				kubeapi.GetResourceMeta = func(client *kubernetes.Clientset, kind string, version string) *kubeapi.ResourceMeta {
					return &kubeapi.ResourceMeta{
						Name:         "Pod",
						Plural:       "pods",
						Path:         "api",
						Namespaced:   true,
						GroupVersion: "v1",
					}
				}
				kubeapi.GetResource = func(ctx context.Context, resourceMeta *kubeapi.ResourceMeta, resourceName string, namespaceName string) ([]byte, error) {
					return []byte("{\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"name\":\"pod-se-plus-mutation\",\"resourceVersion\": \"verse1\",\"uid\": \"31ce6848-bee4-40fb-be85-7f796dd11685\",\"namespace\":\"kate-kblt-dev\",\"labels\":{\"sidecar.istio.io/inject\":\"false\",\"side-effect-plus-mutation\":\"enabled\"},\"annotations\":{\"kblt.annot-ns/merge\":\"enabled\", \"kblt.sideEffect.resource/tag\": \"5\"}},\"spec\":{\"hostNetwork\":false,\"serviceAccount\":\"default\",\"serviceAccountName\":\"default\",\"restartPolicy\":\"Never\",\"automountServiceAccountToken\":false,\"securityContext\":{\"runAsNonRoot\":true,\"seccompProfile\":{\"type\":\"RuntimeDefault\"}},\"containers\":[{\"image\":\"dzo.sw.sbc.space/sbt_dev/ci90000221_fedmesh_dev/federation-demo@sha256:548cc416011c86bb1e2c6d06289aab0771a0f749c044656deaac5fc86d891fea\",\"name\":\"test\",\"imagePullPolicy\":\"Always\",\"securityContext\":{\"allowPrivilegeEscalation\":false,\"capabilities\":{\"drop\":[\"ALL\"]},\"runAsNonRoot\":true,\"privileged\":false}}]}}"), nil
				}
			},
			trigger: v1alpha1.Trigger{
				ObjectMeta: metav1.ObjectMeta{Name: "TriggerName", Namespace: "TriggerNamespace"},
				Spec: v1alpha1.TriggerSpec{
					SideEffectConfigs: []v1alpha1.SideEffectConfig{{
						Name:         "SideEffConfigName",
						TemplateRefs: []string{"templNs/templName"},
					}}},
			},
			template: v1alpha1.Template{
				ObjectMeta: metav1.ObjectMeta{
					Namespace: "templNs",
					Name:      "templName",
				},
				Spec: v1alpha1.TemplateSpec{
					Data: "---\nkind: TriggerInstance\napiVersion: kubelatte.synapse.sber/v1alpha1\nmetadata:\n  name: trigger-instance-se-plus-mutation\n  annotations:\n    kblt/side-effect-plus-mutation: enabled\nspec:\n  data: data\n",
				},
			},
			args: args{
				info: &SE{
					SeMode: int32(Recreation),
					Configs: Configs{
						Kind:       "Pod",
						ApiVersion: "v1",
						Metadata: Metadata{
							Namespace: "kblt-dev",
							Name:      "podik :D ! XD",
						},
						ParentTag:    5,
						TemplateRefs: []string{"templNs/templName"},
						TriggerRef: TriggerRef{
							Name:             "TriggerName",
							Namespace:        "TriggerNamespace",
							SideEffectConfig: "SideEffConfigName",
						},
					},
				}},
		},
		{
			name: "gettimg parent error",
			setVars: func() {
				kubeapi.GetResourceMeta = func(client *kubernetes.Clientset, kind string, version string) *kubeapi.ResourceMeta {
					return &kubeapi.ResourceMeta{
						Name:         "Pod",
						Plural:       "pods",
						Path:         "api",
						Namespaced:   true,
						GroupVersion: "v1",
					}
				}
				operator.TimeoutParentWaiting = 2 * time.Second
				kubeapi.GetResource = func(ctx context.Context, resourceMeta *kubeapi.ResourceMeta, resourceName string, namespaceName string) ([]byte, error) {
					return []byte("{\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"name\":\"pod-se-plus-mutation\",\"resourceVersion\": \"verse1\",\"uid\": \"31ce6848-bee4-40fb-be85-7f796dd11685\",\"namespace\":\"kate-kblt-dev\",\"labels\":{\"sidecar.istio.io/inject\":\"false\",\"side-effect-plus-mutation\":\"enabled\"},\"annotations\":{\"kblt.annot-ns/merge\":\"enabled\", \"kblt.sideEffect.resource/tag\": \"5\"}},\"spec\":{\"hostNetwork\":false,\"serviceAccount\":\"default\",\"serviceAccountName\":\"default\",\"restartPolicy\":\"Never\",\"automountServiceAccountToken\":false,\"securityContext\":{\"runAsNonRoot\":true,\"seccompProfile\":{\"type\":\"RuntimeDefault\"}},\"containers\":[{\"image\":\"dzo.sw.sbc.space/sbt_dev/ci90000221_fedmesh_dev/federation-demo@sha256:548cc416011c86bb1e2c6d06289aab0771a0f749c044656deaac5fc86d891fea\",\"name\":\"test\",\"imagePullPolicy\":\"Always\",\"securityContext\":{\"allowPrivilegeEscalation\":false,\"capabilities\":{\"drop\":[\"ALL\"]},\"runAsNonRoot\":true,\"privileged\":false}}]}}"), errors.New("")
				}
			},
			trigger: v1alpha1.Trigger{
				ObjectMeta: metav1.ObjectMeta{Name: "TriggerName", Namespace: "TriggerNamespace"},
				Spec: v1alpha1.TriggerSpec{
					SideEffectConfigs: []v1alpha1.SideEffectConfig{{
						Name:         "SideEffConfigName",
						TemplateRefs: []string{"templNs/templName"},
					}}},
			},
			template: v1alpha1.Template{
				ObjectMeta: metav1.ObjectMeta{
					Namespace: "templNs",
					Name:      "templName",
				},
				Spec: v1alpha1.TemplateSpec{
					Data: "---\nkind: TriggerInstance\napiVersion: kubelatte.synapse.sber/v1alpha1\nmetadata:\n  name: trigger-instance-se-plus-mutation\n  annotations:\n    kblt/side-effect-plus-mutation: enabled\nspec:\n  data: data\n",
				},
			},
			args: args{
				info: &SE{
					SeMode: int32(Recreation),
					Configs: Configs{
						Kind:       "Pod",
						ApiVersion: "v1",
						Metadata: Metadata{
							Namespace: "kblt-dev",
							Name:      "podik :D ! XD",
						},
						ParentTag:    5,
						TemplateRefs: []string{"templNs/templName"},
						TriggerRef: TriggerRef{
							Name:             "TriggerName",
							Namespace:        "TriggerNamespace",
							SideEffectConfig: "SideEffConfigName",
						},
					},
				}},
		},
		{
			name: "no templates",
			setVars: func() {
				kubeapi.GetResourceMeta = func(client *kubernetes.Clientset, kind string, version string) *kubeapi.ResourceMeta {
					return &kubeapi.ResourceMeta{
						Name:         "Pod",
						Plural:       "pods",
						Path:         "api",
						Namespaced:   true,
						GroupVersion: "v1",
					}
				}
				operator.TimeoutParentWaiting = 2 * time.Second
				kubeapi.GetResource = func(ctx context.Context, resourceMeta *kubeapi.ResourceMeta, resourceName string, namespaceName string) ([]byte, error) {
					return []byte("{\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"name\":\"pod-se-plus-mutation\",\"resourceVersion\": \"verse1\",\"uid\": \"31ce6848-bee4-40fb-be85-7f796dd11685\",\"namespace\":\"kate-kblt-dev\",\"labels\":{\"sidecar.istio.io/inject\":\"false\",\"side-effect-plus-mutation\":\"enabled\"},\"annotations\":{\"kblt.annot-ns/merge\":\"enabled\", \"kblt.sideEffect.resource/tag\": \"5\"}},\"spec\":{\"hostNetwork\":false,\"serviceAccount\":\"default\",\"serviceAccountName\":\"default\",\"restartPolicy\":\"Never\",\"automountServiceAccountToken\":false,\"securityContext\":{\"runAsNonRoot\":true,\"seccompProfile\":{\"type\":\"RuntimeDefault\"}},\"containers\":[{\"image\":\"dzo.sw.sbc.space/sbt_dev/ci90000221_fedmesh_dev/federation-demo@sha256:548cc416011c86bb1e2c6d06289aab0771a0f749c044656deaac5fc86d891fea\",\"name\":\"test\",\"imagePullPolicy\":\"Always\",\"securityContext\":{\"allowPrivilegeEscalation\":false,\"capabilities\":{\"drop\":[\"ALL\"]},\"runAsNonRoot\":true,\"privileged\":false}}]}}"), errors.New("")
				}
			},
			trigger: v1alpha1.Trigger{
				ObjectMeta: metav1.ObjectMeta{Name: "TriggerName", Namespace: "TriggerNamespace"},
				Spec: v1alpha1.TriggerSpec{
					SideEffectConfigs: []v1alpha1.SideEffectConfig{{
						Name:         "SideEffConfigName",
						TemplateRefs: []string{"templNs/templName"},
					}}},
			},
			template: v1alpha1.Template{
				ObjectMeta: metav1.ObjectMeta{
					Namespace: "templNs",
					Name:      "templName",
				},
				Spec: v1alpha1.TemplateSpec{
					Data: "---\nkind: TriggerInstance\napiVersion: kubelatte.synapse.sber/v1alpha1\nmetadata:\n  name: trigger-instance-se-plus-mutation\n  annotations:\n    kblt/side-effect-plus-mutation: enabled\nspec:\n  data: data\n",
				},
			},
			args: args{
				info: &SE{
					SeMode: int32(Recreation),
					Configs: Configs{
						Kind:       "Pod",
						ApiVersion: "v1",
						Metadata: Metadata{
							Namespace: "kblt-dev",
							Name:      "podik :D ! XD",
						},
						ParentTag:    5,
						TemplateRefs: []string{"templNs/templName"},
						TriggerRef: TriggerRef{
							Name:             "TriggerName",
							Namespace:        "TriggerNamespace",
							SideEffectConfig: "SideEffConfigName",
						},
					},
				}},
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			tt.setVars()

			triggerInstanceClient := mocks2.NewTriggerInstanceInterface(t)
			triggerInstanceClient.On("Get", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, errors2.NewNotFound(schema.GroupResource{}, "ti")).Maybe()
			triggerInstanceClient.On("Create", mock.Anything, mock.Anything, mock.Anything).Return(nil, nil).Maybe()
			triggerInstanceClient.On("Delete", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil).Maybe()
			triggerInstanceClient.On("List", mock.Anything, mock.Anything, mock.Anything).Return(&v1alpha1.TriggerInstanceList{
				Items: []v1alpha1.TriggerInstance{{
					TypeMeta: metav1.TypeMeta{
						Kind:       "",
						APIVersion: "",
					},
					ObjectMeta: metav1.ObjectMeta{
						Name:   "",
						Labels: nil,
						Annotations: map[string]string{
							annotSideEffConfigName: "SideEffConfigName",
							annotTriggerNamespace:  "TriggerNamespace",
							annotTriggerName:       "TriggerName",
							annotParentHash:        "12345677",
						},
					},
					Spec:   v1alpha1.TriggerInstanceSpec{},
					Status: v1alpha1.TriggerInstanceStatus{},
				}},
			}, nil).Maybe()

			kbtlKubeClientMock := mocks2.NewV1Alpha1Interface(t)
			kbtlKubeClientMock.On("TriggerInstance").Return(triggerInstanceClient).Maybe()

			storage.Storage = &storage.StorageController{}
			storage.Storage.Start(false, false)
			storage.Storage.UpdateTemplate(bell.Message{Value: tt.template})
			storage.Storage.UpdateTrigger(bell.Message{Value: tt.trigger})

			c := Executor{kbtlKubeClient: kbtlKubeClientMock, mu: &sync.Mutex{}}
			c.applySideEffectRecreate(context.Background(), tt.args.info)
		})
	}
}
